use std::collections::BinaryHeap;
use std::collections::HashMap;
use std::collections::HashSet;

fn main() {
    println!("Hello, world!");
    let vara: bool = true;
    println!("{}", vara);
    let varb: i8 = 9;
    println!("{}", varb);
    let varc: char = '永';
    println!("{}", varc);
    let vard = "永远";
    println!("{}", vard);
    let vare = b"\x7f\x49";
    println!("{:?}", vare);
    let varf = [1, 2, 3, 4, 5];
    println!("{:?}", varf);

    if 8 + 255 == 253 {
        println!("8 + 255 == 253");
    } else {
        println!("8 + 255 != 253");
    }
    let opc = '+';
    match opc {
        '+' => println!("加法"),
        '-' => println!("减法"),
        '*' => println!("乘法"),
        '/' => println!("除法"),
        _ => println!("未知操作符"),
    }
    for i in 0..10 {
        println!("{}", i);
    }
    // 输出斐波那契数列
    let mut a = 0;
    let mut b = 1;
    println!("斐波那契数列：");
    while b < 1000 {
        println!("{}", b);
        let c = a + b;
        a = b;
        b = c;
    }
    let num1 = 5;
    let num2 = 7;
    let sum = add(num1, num2); // 调用 add 函数求和
    println!("{} + {} = {}", num1, num2, sum); // 打印结果

    // 定义一个结构体，用来描述一个人
    let person = Person {
        name: String::from("张三"),
        age: 20,
        gender: String::from("男"),
    };
    person.print(); // 调用 print 方法打印信息
                    // 定义一个Person实例
    let person1 = Person {
        name: String::from("李四"),
        age: 25,
        gender: String::from("女"),
    };
    person1.print(); // 调用 print 方法打印信息
                     // 调用 elder_person 关联函数，返回年龄大的那个
    let elder = Person::elder_person(&person, &person1);
    println!("年龄大的那个是:{}", elder.name);
    // 定义一个枚举，用来描述身份，包括两个成员：名字和编号
    let identity = Identity::Name(String::from("张三"));
    println!("身份是：{:?}", identity); // 使用 {:?} 进行调试打印

    let identity1 = Identity::Id(1001);
    println!("身份是：{:?}", identity1); // 使用 {:?} 进行调试打印
                                         // 使用match来处理枚举
    match identity1 {
        Identity::Name(name) => println!("名字是：{}", name),
        Identity::Id(id) => println!("编号是：{}", id),
    }
    let mut x = 5; // 将 x 声明为可变变量
    let y = &x;
    println!("y = {}", y); // 打印 y 的值
    let x_ref = &mut x; // 使用不同的变量名避免冲突
    *x_ref += 6; // 通过解引用来修改它的值，解决编译错误
    println!("x = {}", x); // 打印 x 的值
                           // 定义一个二维向量，用来存储矩阵
    let matrix: Vec<Vec<i32>> = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
    // 打印矩阵
    for (i, row) in matrix.iter().enumerate() {
        for (j, col) in row.iter().enumerate() {
            print!("{} ", col);
        }
        println!(""); // 换行
    }
    println!("{:?}", matrix); // 使用 {:?} 进行调试打印
                              // 定义两个向量，用来存储两个数列
    let mut a1 = vec![1, 2, 3];
    let mut b1 = vec![4, 5, 6];
    // 打印上面两个向量
    println!("a1 = {:?}, b1 = {:?}", a1, b1);
    // 把向量b1拼接到a1尾部
    a1.append(&mut b1);
    // 打印合并后的向量
    println!("a1 = {:?}, b1 = {:?}", a1, b1);
    // 删除a1中索引为3的元素，并且把此元素追加到b1尾部
    b1.push(a1.remove(3));
    // 打印修改后的向量
    println!("a1 = {:?}, b1 = {:?}", a1, b1);
    a1.pop();
    // 打印修改后的向量
    println!("a1 = {:?}, b1 = {:?}", a1, b1);
    // 定义一个字典，键是编号，值是分数
    let mut scores = HashMap::new();
    scores.insert(1, 90);
    scores.insert(2, 80);
    scores.insert(3, 70);
    // 打印字典
    println!("{:?}", scores);
    // 通过键来获取分数
    let score = scores.get(&1);
    // 打印分数
    println!("分数是：{:?}", score);
    // 通过键来删除分数
    scores.remove(&1);
    // 打印字典
    println!("{:?}", scores);
    // 遍历字典，每个值都加100
    for (key, value) in &mut scores {
        *value += 100;
    }
    // 遍历字典
    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }

    // 定义一个集合，存储学生
    let mut students = HashSet::new();
    // 添加学生
    students.insert("张三");
    students.insert("李四");
    students.insert("王五");
    // 打印学生
    println!("{:?}", students);
    // 通过键来获取学生
    let student = students.get("张三");
    // 打印学生
    println!("学生是：{:?}", student);
    // 通过键来删除学生
    students.remove("张三");
    // 打印学生
    println!("{:?}", students);
    // 遍历学生
    for student in &students {
        println!("{}", student);
    }
    // 定义一个优先队列，用来存储优先级
    let mut queue = BinaryHeap::new();
    // 添加优先级
    queue.push(10);
    queue.push(5);
    queue.push(100);
    queue.push(1000);
    // 打印优先级
    println!("{:?}", queue);
    // 获取优先级
    let priority = queue.pop();
    // 打印优先级
    println!("{:?}", priority);
    // 遍历优先级
    for priority in &queue {
        println!("{}", priority);
    }
    // 依次弹出所有优先级
    while let Some(priority) = queue.pop() {
        println!("{}", priority);
    }
    let var1 = Some(8);
    if let Some(x) = var1 {
        println!("{}", x);
    } else {
        println!("None");
    }
    let dish = ("Ham", "Eggs");
    if let ("Bacon", b) = dish {
        println!("Bacon is served with {}", b);
    } else {
        println!("No bacon will be served");
    }
    let a = Foo::Bar;
    if let Foo::Bar = a {
        println!("a is foobar");
    } else {
        println!("a is foobaz")
    }
    let mut stack = vec![1, 2, 3];
    while let Some(x) = stack.pop() {
        println!("{}", x);
    }
    let var_i32 = 5; // 默认数据保存在栈上
    let b = Box::new(var_i32); // 使用Box后数据会存储在堆上
    println!("{}", var_i32);
    println!("b = {}", b);

    let var_string = String::from("Hello"); // var_string 是一个 String 类型
    let b = Box::new(var_string); // var_string 被移动到 Box 中
    // println!("var_string = {}", var_string); // 这行会报错，因为 var_string 已经被移动
    println!("b = {}", b); // b 指向堆上的 String，输出 "Hello"
}
enum Foo {
    Bar,
    Baz,
}
// 定义一个函数，接受两个参数 a 和 b，返回它们的和
fn add(a: i32, b: i32) -> i32 {
    a + b // 返回 a 和 b 的和
}
// 定义一个结构体，用来描述一个人
#[derive(Debug)]
struct Person {
    name: String,   // 姓名
    age: u8,        // 年龄
    gender: String, // 性别
}

// 为 Person 实现关联函数 elder_person
impl Person {
    fn elder_person<'a>(a: &'a Person, b: &'a Person) -> &'a Person {
        if a.age > b.age {
            a
        } else {
            b
        }
    }
}
// 定义一个trait,包含一个打印方法
trait Print {
    fn print(&self);
}
// 为结构体 Person 实现 Print trait
impl Print for Person {
    fn print(&self) {
        println!("{}的年龄是{}，性别是{}", self.name, self.age, self.gender);
    }
}
// 定义一个枚举，用来描述身份，包括两个成员：名字和编号
#[derive(Debug)] // 添加这一行来自动实现Debug trait
enum Identity {
    Name(String),
    Id(u32),
}
